package microcredit.gui.handler;

import java.awt.Component;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import microcredit.gui.editor.AbstractEditorForm;
import microcredit.gui.editor.EditorPanel;
import microcredit.gui.editor.training.TrainingTypeGeneralForm;
import microcredit.gui.editor.training.TrainingTypeMemberForm;
import microcredit.gui.selector.IFilter;
import microcredit.gui.selector.SelectorPanel;
import microcredit.gui.selector.SelectorPanel.SelectorDialog;
import microcredit.gui.table.BeanTable.SelectionMode;
import microcredit.model.TrainingType;
import microcredit.model.bo.BOTraining;
import microcredit.model.domain.Status;

public class TrainingHandler extends AbstractHandler<TrainingType>{

	private final Component parent;
	
	public TrainingHandler(Component parent) {
		this.parent = parent;
	}
	
	@Override
	public TrainingType open(Component component, TrainingType e)
			throws Throwable {
		return showEditor(component, e);
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public List<IFilter<TrainingType>> getFilters() {
		return Arrays.asList(new TrainingNameFilter(), new TrainingStatusFilter());
	}
	
	@Override
	public void choose() throws Throwable {
		TrainingHandler handler = new TrainingHandler(parent);
		
		SelectorDialog<TrainingType> dialog = SelectorPanel.createDialog(parent, "Select training type", TrainingType.class, handler, null, null, null, handler, null, null, null);
		dialog.getSelectorPanel().setSelectionMode(SelectionMode.SINGLE);
		dialog.setVisible(true);
		
		List<TrainingType> members = dialog.getSelectedElements();
		if (members == null || members.size() <= 0) {
			return;
		}
		//TODO
	}
	
	@Override
	public void delete(TrainingType e) throws Throwable {
		BOTraining.create().deleteTraining(e);
	}
	
	@Override
	public String toString(TrainingType element) {
		return element.getCumulatedName();
	}
	
	@Override
	public TrainingType newEntity(Component parent) throws Throwable {
		TrainingType type = new TrainingType();
		type.setStatus(Status.A);
		return showEditor(parent, type);
	}
	
	private TrainingType showEditor(Component parent, TrainingType t) {
		List<AbstractEditorForm<TrainingType>> forms = new ArrayList<AbstractEditorForm<TrainingType>>();
		forms.add(new TrainingTypeGeneralForm());
		forms.add(new TrainingTypeMemberForm());
		TrainingType type = EditorPanel.showEditorDialog(parent, "Edit", TrainingType.class, t, this, this, null, forms);
		return type;
	}
	
	@Override
	public TrainingType refresh(TrainingType element) throws Throwable {
		return super.refresh(element);
	}
	
	@Override
	public TrainingType save(TrainingType entity) throws Throwable {
		return BOTraining.create().saveTraining(entity);
	}
	
	@Override
	public List<TrainingType> load() throws Throwable {
		return BOTraining.create().readTrainings();
	}
	

	protected final class TrainingStatusFilter implements IFilter<TrainingType> {
		@Override
		public String getLabel() {
			return "Status";
		}

		@Override
		public List<? extends Object> getValues() {
			return Arrays.asList(Status.values());
		}
		@Override
		public Object getSelectedValue() {
			return null;
		}

		@Override
		public void filter(Object oexp, List<TrainingType> entities) {
			Status exp = (Status)oexp;
				
			for (Iterator<TrainingType> iterator = entities.iterator(); iterator
					.hasNext();) {
				TrainingType member = iterator.next();
				if (member.getStatus() != exp) {
					iterator.remove();
				}
			}
		}
	}
	
	protected final class TrainingNameFilter implements IFilter<TrainingType> {
		@Override
		public String getLabel() {
			return "Name";
		}

		@Override
		public List<Object> getValues() {
			return null;
		}
		
		@Override
		public Object getSelectedValue() {
			return null;
		}

		@Override
		public void filter(Object oexp, List<TrainingType> entities) {
			String exp = ((String)oexp).toLowerCase();
			String[] expressions = exp.split("\\ ");
			for (Iterator<TrainingType> iterator = entities.iterator(); iterator.hasNext();) {
				TrainingType member = iterator.next();
				String fullName = member.getCumulatedName().toLowerCase();
				for (String subExp : expressions) {
					if (fullName.indexOf(subExp) == -1) {
						iterator.remove();
						break;
					}
				} 
			}
		}
	}
	
}
